
package com.hlkj.pay.service.ad.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.framework.mybatis.core.query.QueryWrapperX;
import com.hlkj.framework.mybatis.core.utils.MyBatisUtils;
import com.hlkj.pay.common.constants.RedisConstants;
import com.hlkj.pay.dto.ad.AdPayOrderDto;
import com.hlkj.pay.dto.ad.query.AdPayOrderQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.infrastructure.mapper.ad.AdPayOrderMapper;
import com.hlkj.pay.infrastructure.model.ad.AdPayOrderDO;
import com.hlkj.pay.service.ad.IAdPayOrderService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/23 11:38
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdPayOrderServiceImpl implements IAdPayOrderService {

    private final AdPayOrderMapper adPayOrderMapper;

    @Override
    public PageResult<AdPayOrderDto> queryPage(AdPayOrderQueryDto adPayOrderQueryDto) {
        adPayOrderQueryDto.setSortingFields("po.id");
        IPage<AdPayOrderDto> mpPage = MyBatisUtils.buildPage(adPayOrderQueryDto);
        QueryWrapper<AdPayOrderDto> queryWrapper = buildWrapper(adPayOrderQueryDto);
        adPayOrderMapper.selectPayPage(mpPage, queryWrapper);
        return new PageResult(mpPage.getRecords(), mpPage.getTotal(), mpPage.getCurrent(), mpPage.getSize(), mpPage.getPages());
    }

    @Override
    public Long queryCount(AdPayOrderQueryDto adPayOrderQueryDto) {
        return adPayOrderMapper.selectCount(buildCountWrapper(adPayOrderQueryDto));
    }

    @Override
    @Cacheable(value = RedisConstants.AD_PAY_ORDER_INFO, key = "#mchOrderNo", unless = "#result == null")
    public AdPayOrderDO queryDetailCache(String mchOrderNo) {
        return adPayOrderMapper.selectOne(AdPayOrderDO::getMchOrderNo, mchOrderNo);
    }

    @Override
    public AdPayOrderDO queryDetail(String mchOrderNo) {
        return adPayOrderMapper.selectOne(AdPayOrderDO::getMchOrderNo, mchOrderNo);
    }

    @Override
    public AdPayOrderDO queryDetailByInsOrderNo(String insOrderNo) {
        return adPayOrderMapper.selectOne(AdPayOrderDO::getInsOrderNo, insOrderNo);
    }

    @Override
    @CacheEvict(value = RedisConstants.AD_PAY_ORDER_INFO, key = "#mchOrderNo")
    public void updatePayOrder(String mchOrderNo, AdPayOrderDO updatePayOrderDO) {
        adPayOrderMapper.updateById(updatePayOrderDO);
    }

    @Override
    public int updatePayOrderStatus(String mchOrderNo, AdPayOrderDO updatePayOrderDO) {
        Long id = updatePayOrderDO.getId();
        LambdaQueryWrapper<AdPayOrderDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AdPayOrderDO::getId, id);
        lambdaQueryWrapper.ne(AdPayOrderDO::getState, updatePayOrderDO.getState());
        updatePayOrderDO.setId(null);
        return adPayOrderMapper.update(updatePayOrderDO, lambdaQueryWrapper);
    }

    @Override
    @CachePut(value = RedisConstants.AD_PAY_ORDER_INFO, key = "#payOrderDO.mchOrderNo")
    public AdPayOrderDO addPayOrder(AdPayOrderDO payOrderDO) {
        adPayOrderMapper.insert(payOrderDO);
        return payOrderDO;
    }

    @Override
    public void updateCallOrder(Long adId, int callOrderCount, String callOrderNo) {
        adPayOrderMapper.updateCallOrder(adId, callOrderCount, callOrderNo);
    }

    @Override
    public void updateCallOrderAll(Long id, String callOrderNo) {
        AdPayOrderDO adPayOrderDO = new AdPayOrderDO();
        adPayOrderDO.setId(id);
        adPayOrderDO.setCallOrderNo(callOrderNo);
        adPayOrderDO.setCallStatus(CommonEnum.YES_NO_TYPE.YES.getCode());
        adPayOrderMapper.updateById(adPayOrderDO);
    }

    /**
     * 查询条件封装
     *
     * @param adPayOrderQueryDto
     * @return
     */
    LambdaQueryWrapperX<AdPayOrderDO> buildCountWrapper(AdPayOrderQueryDto adPayOrderQueryDto) {
        LambdaQueryWrapperX<AdPayOrderDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(AdPayOrderDO::getAdId, adPayOrderQueryDto.getAdId());
        queryWrapper.eqIfPresent(AdPayOrderDO::getState, adPayOrderQueryDto.getState());
        return queryWrapper;
    }

    /**
     * 查询条件封装
     *
     * @param adPayOrderQueryDto
     * @return
     */
    QueryWrapper<AdPayOrderDto> buildWrapper(AdPayOrderQueryDto adPayOrderQueryDto) {
        QueryWrapperX<AdPayOrderDto> queryWrapper = new QueryWrapperX<>();
        queryWrapper.likeIfPresent( "po.mch_order_no", adPayOrderQueryDto.getMchOrderNo());
        queryWrapper.likeIfPresent( "po.pay_order_no", adPayOrderQueryDto.getPayOrderNo());
        queryWrapper.likeIfPresent( "po.ins_order_no", adPayOrderQueryDto.getInsOrderNo());
        if (StringUtils.hasText(adPayOrderQueryDto.getLikeOrderNo())) {
            queryWrapper.like("po.mch_order_no", adPayOrderQueryDto.getLikeOrderNo()).or().like("po.pay_order_no", adPayOrderQueryDto.getLikeOrderNo()).or()
                    .like("po.ins_order_no", adPayOrderQueryDto.getLikeOrderNo()).or().like("po.channel_order_no", adPayOrderQueryDto.getLikeOrderNo());
        }
        queryWrapper.eqIfPresent( "po.sn", adPayOrderQueryDto.getSn());
        queryWrapper.eqIfPresent( "po.phone", adPayOrderQueryDto.getPhone());
        queryWrapper.eqIfPresent( "po.app_id", adPayOrderQueryDto.getAppId());
        queryWrapper.eqIfPresent("po.state", adPayOrderQueryDto.getState());
        queryWrapper.eqIfPresent("po.refund_status", adPayOrderQueryDto.getRefundStatus());
        queryWrapper.eqIfPresent( "po.call_status", adPayOrderQueryDto.getCallStatus());
        queryWrapper.isNotNull(adPayOrderQueryDto.isExistAOId(), "po.tui_id");
        queryWrapper.eqIfPresent( "po.order_source", adPayOrderQueryDto.getOrderSource());
        queryWrapper.eqIfPresent("po.ad_id", adPayOrderQueryDto.getAdId());
        queryWrapper.likeIfPresent( "info.name", adPayOrderQueryDto.getAdName());
        queryWrapper.eqIfPresent( "info.type", adPayOrderQueryDto.getAdType());
        queryWrapper.eqIfPresent("info.media_id", adPayOrderQueryDto.getMediaId());
        queryWrapper.geIfPresent("po.create_time", adPayOrderQueryDto.getStartQueryTime());
        queryWrapper.leIfPresent("po.create_time", adPayOrderQueryDto.getEndQueryTime());
        queryWrapper.geIfPresent( "po.amount", adPayOrderQueryDto.getMinAmount());
        queryWrapper.leIfPresent("po.amount", adPayOrderQueryDto.getMaxAmount());
        return queryWrapper;
    }
}
